package neu.dreamera.activity;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Camera;
import android.location.Criteria;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.commonsware.cwac.camera.CameraHost;
import com.commonsware.cwac.camera.CameraHostProvider;
import com.commonsware.cwac.camera.CameraView;
import com.commonsware.cwac.camera.PictureTransaction;
import com.commonsware.cwac.camera.SimpleCameraHost;
import com.commonsware.cwac.camera.ZoomTransaction;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import neu.dreamera.R;
import neu.dreamera.utils.FileCacheUtil;
import neu.dreamera.utils.ImgToolKits;
import neu.dreamera.utils.ZoomListener;
import neu.dreamera.view.RevealBackgroundView;

import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;


/**
 * Created by root on 16-7-27.
 */
public class CameraActivityplus extends AppCompatActivity implements
        RevealBackgroundView.OnStateChangeListener, CameraHostProvider {

    public static final String ARG_REVEAL_START_LOCATION = "reveal_start_location";
    public static final String TAG = "CameraActivityplus";

    @Bind(R.id.vRevealBackground)
    RevealBackgroundView vRevealBackground;
    @Bind(R.id.vPhotoRoot)
    View vTakePhotoRoot;
    @Bind(R.id.cameraView)
    CameraView cameraView;
    @Bind(R.id.btnTakePhoto)
    Button btnTakePhoto;


    //private String pictureID; //从上一个Activity传递过来的图片的ID
    private String picturePath;
    private SurfaceView surfaceView; //绘制边缘图
    private SurfaceHolder surfaceHolder;
    private int zoom = 0; //相机焦距

    private Bitmap picFromFile;
    private Bitmap borderBitmap;
    private WindowManager wm;
    private WindowManager.LayoutParams wmParams;
    private Matrix lastMatrix = new Matrix();

    private Canvas canvas;

    private TextView current_longitude;
    private TextView current_latitude;


    Handler handler;
    private static final int ADD_BORDER_PICTURE = 1;


    private String picture_path;
    private int point_id;


    private String longitude = new String("");
    private String latitude = new String("");


    private LocationManager lm;
    //private static final String TAG = "GpsActivity";


    /**
     * 加载OpenCV的回调函数，用此函数在手机上安装OpenCV Manager
     * @author 10405
     */
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS: {
                    Log.d("CameraActivityplus", "Load success");
                }
                break;
                default: {
                    super.onManagerConnected(status);
                }
                break;
            }
        }
    };

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, 1);

        Log.d("CameraActivityplus", "oncreate()");
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_camera_plus);
        ButterKnife.bind(this);

        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//        lm.setTestProviderEnabled("gps", true);

        if (!OpenCVLoader.initDebug()) {  // 加载OpenCV
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
        } else {
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
        current_longitude = (TextView) findViewById(R.id.current_longitude);
        current_latitude = (TextView) findViewById(R.id.current_latitude);


        //setupRevealBackground(savedInstanceState);
        Intent i = getIntent();
        Bundle b = i.getExtras();
        point_id = b.getInt("point_id");


        // 判断GPS是否正常启动
//        if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//            Toast.makeText(this, "请开启GPS导航...", Toast.LENGTH_SHORT).show();
//            // 返回开启GPS导航设置界面
//            Intent in = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
//            startActivityForResult(in, 0);
//            return;
//        }

        // 为获取地理位置信息时设置查询条件
        String bestProvider = lm.getBestProvider(getCriteria(), true);
        // 获取位置信息
        // 如果不设置查询要求，getLastKnownLocation方法传人的参数为LocationManager.GPS_PROVIDER
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Location location = lm.getLastKnownLocation(bestProvider);
//        while (location == null) {
//            location = lm.getLastKnownLocation(bestProvider);
//        }
        updateView(location);
        // 监听状态
        lm.addGpsStatusListener(listener);
        // 绑定监听，有4个参数
        // 参数1，设备：有GPS_PROVIDER和NETWORK_PROVIDER两种
        // 参数2，位置信息更新周期，单位毫秒
        // 参数3，位置变化最小距离：当位置距离变化超过此值时，将更新位置信息
        // 参数4，监听
        // 备注：参数2和3，如果参数3不为0，则以参数3为准；参数3为0，则通过时间来定时更新；两者为0，则随时刷新

        // 1秒更新一次，或最小位移变化超过1米更新一次；
        // 注意：此处更新准确度非常低，推荐在service里面启动一个Thread，在run中sleep(10000);然后执行handler.sendMessage(),更新位置
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);


    }//end create()

    // 位置监听
    private LocationListener locationListener = new LocationListener() {

        /**
         * 位置信息变化时触发
         */
        public void onLocationChanged(Location location) {
            updateView(location);
            Log.i(TAG, "时间：" + location.getTime());
            Log.i(TAG, "经度：" + location.getLongitude());
            Log.i(TAG, "纬度：" + location.getLatitude());
            Log.i(TAG, "海拔：" + location.getAltitude());
        }

        /**
         * GPS状态变化时触发
         */
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                // GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    Log.i(TAG, "当前GPS状态为可见状态");
                    break;
                // GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    Log.i(TAG, "当前GPS状态为服务区外状态");
                    break;
                // GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    Log.i(TAG, "当前GPS状态为暂停服务状态");
                    break;
            }
        }

        /**
         * GPS开启时触发
         */
        public void onProviderEnabled(String provider) {
            if (ActivityCompat.checkSelfPermission(CameraActivityplus.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(CameraActivityplus.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            Location location = lm.getLastKnownLocation(provider);
            updateView(location);
        }

        /**
         * GPS禁用时触发
         */
        public void onProviderDisabled(String provider) {
            updateView(null);
        }

    };

    // 状态监听
    GpsStatus.Listener listener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            switch (event) {
                // 第一次定位
                case GpsStatus.GPS_EVENT_FIRST_FIX:
                    Log.i(TAG, "第一次定位");
                    break;
                // 卫星状态改变
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                    Log.i(TAG, "卫星状态改变");
                    // 获取当前状态
                    GpsStatus gpsStatus = lm.getGpsStatus(null);
                    // 获取卫星颗数的默认最大值
                    int maxSatellites = gpsStatus.getMaxSatellites();
                    // 创建一个迭代器保存所有卫星
                    Iterator<GpsSatellite> iters = gpsStatus.getSatellites()
                            .iterator();
                    int count = 0;
                    while (iters.hasNext() && count <= maxSatellites) {
                        GpsSatellite s = iters.next();
                        count++;
                    }
                    System.out.println("搜索到：" + count + "颗卫星");
                    break;
                // 定位启动
                case GpsStatus.GPS_EVENT_STARTED:
                    Log.i(TAG, "定位启动");
                    break;
                // 定位结束
                case GpsStatus.GPS_EVENT_STOPPED:
                    Log.i(TAG, "定位结束");
                    break;
            }
        }

        ;
    };

    /**
     * 实时更新文本内容
     *
     * @param location
     */
    private void updateView(Location location) {
        if (location != null) {


            current_longitude.setText(String.valueOf(location.getLongitude()));
            current_latitude.setText(String.valueOf(location.getLatitude()));
            longitude=current_longitude.getText().toString();
            latitude=current_latitude.getText().toString();
            Log.d(TAG, "longitude is " + longitude);
            Log.d(TAG, "latitude is " + latitude);
        } else {
            // 清空EditText对象
            current_latitude.setText("");
            current_longitude.setText("");
        }
    }


    private Criteria getCriteria() {
        Criteria criteria = new Criteria();
        // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略，Criteria.ACCURACY_FINE则比较精细
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        // 设置是否要求速度
        criteria.setSpeedRequired(false);
        // 设置是否允许运营商收费
        criteria.setCostAllowed(false);
        // 设置是否需要方位信息
        criteria.setBearingRequired(false);
        // 设置是否需要海拔信息
        criteria.setAltitudeRequired(false);
        // 设置对电源的需求
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        return criteria;
    }








/*
    private void setupRevealBackground(Bundle savedInstanceState) {
        vRevealBackground.setFillPaintColor(0xFF16181a);
        vRevealBackground.setOnStateChangeListener(this);
        if (savedInstanceState == null) {
            final int[] startingLocation = getIntent().getIntArrayExtra(ARG_REVEAL_START_LOCATION);
            vRevealBackground.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    vRevealBackground.getViewTreeObserver().removeOnPreDrawListener(this);
                    vRevealBackground.startFromLocation(startingLocation);
                    return true;
                }
            });
        } else {
            vRevealBackground.setToFinishedFrame();
        }
    }
*/

    @Override
    protected void onResume() {
        Log.d("CameraActivityplus", "Onresume()");
        super.onResume();
        cameraView.onResume();

        handler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case ADD_BORDER_PICTURE:
                        //在这里可以进行UI操
                        Log.d(TAG, "run addBorderPicture after get the handler");
                        addBorderPicture();
                        break;
                    default:
                        break;
                }
            }
        };
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            Uri uri;
            uri = data.getData();
            //file_path=uri.getPath();
            Log.d(TAG, uri.toString());
            picture_path = getRealFilePath(CameraActivityplus.this, uri);
            Log.d(TAG, "picture_path is " + picture_path);
            ContentResolver cr = this.getContentResolver();
            try {
                picFromFile = BitmapFactory.decodeStream(cr.openInputStream(uri));
                //picFromFile.compress(Bitmap.CompressFormat.JPEG, 80);
                Log.d(TAG, "picture_map is " + picFromFile.toString());
            } catch (FileNotFoundException e) {
                Log.e(TAG, e.getMessage(), e);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
        Message message = new Message();
        message.what = ADD_BORDER_PICTURE;
        handler.sendMessage(message); // 将Message对象发送出去,
        Log.d(TAG, "send the message");
    }


    public static String getRealFilePath(final Context context, final Uri uri) {
        if (null == uri) return null;
        final String scheme = uri.getScheme();
        String data = null;
        if (scheme == null)
            data = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    if (index > -1) {
                        data = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        return data;
    }


    @Override
    protected void onPause() {
        Log.d("CameraActivityplus", "OnPause()");
        super.onPause();
        cameraView.onPause();
        // 为了避免onPause后转偏旋转90度
        //this.finish(); //强制退出
    }

    @Override
    protected void onDestroy() {
        Log.d("CameraActivityplus", "Ondestroy()");
        super.onDestroy();
        //当activity 被destory时需要立即清除之前加载的view，否则会出现窗体泄露异常
        wm.removeViewImmediate(surfaceView);
        picFromFile = null;

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        lm.removeUpdates(locationListener);

    }

    @OnClick(R.id.btnTakePhoto)
    public void onTakePhotoClick() {
        //save location;
        //get location


        //longitude= current_longitude.getText().toString();
        //latitude=current_latitude.getText().toString();



        if(latitude.equals("")||longitude.equals("")){
            Log.d(TAG,"show the message of the location!");
            Toast.makeText(CameraActivityplus.this,"The Dreamera is geting your locatoion!please wait a minute.",Toast.LENGTH_SHORT);
        }
        else {
            Intent intent = new Intent();
            intent.setClass(CameraActivityplus.this, AddPictureActivity.class);
            intent.putExtra("picture_path", picture_path);
            intent.putExtra("longitude", longitude);
            intent.putExtra("latitude", latitude);
            intent.putExtra("point_id", point_id);
            startActivity(intent);
            Log.d(TAG, "turn to upload activity");
        }
    }



    @OnClick(R.id.btnCloseCamera)
    public void onCloseCamera() {
        onBackPressed();
    }

    @Override
    public void onStateChange(int state) {
        if (RevealBackgroundView.STATE_FINISHED == state) {
            vTakePhotoRoot.setVisibility(View.VISIBLE);
            addBorderPicture(); //添加边缘图
        } else {
            vTakePhotoRoot.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * 相机预览界面缩小（也就是焦距缩小？）
     * @author 10405
     */
    @OnClick(R.id.smaller)
    public void onZoomSmaller(){
        try{
            zoom -= 6;
            zoom = zoom < 0 ? 0 : zoom;
            ZoomTransaction z = cameraView.zoomTo(zoom);
            z.go();
        }catch (IllegalArgumentException e){
            e.printStackTrace();
        }
    }


    /**
     * 相机预览界面放大（也就是焦距变大？）
     * @author 10405
     */
    @OnClick(R.id.bigger)
    public void onZoomBigger(){
        try{
            zoom += 6;
            ZoomTransaction z = cameraView.zoomTo(zoom);
            z.go();
        }catch (IllegalArgumentException e){
            e.printStackTrace();
        }
    }


    /**
     * 添加轮廓图
     * @author 10405
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public void addBorderPicture(){
/*
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();//从上一个Activity获取参数图片
     */
        Log.d(TAG,"addBorderPicture()");
        wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);

        borderBitmap = ImgToolKits.initBorderPic(
                picFromFile,
                wm.getDefaultDisplay().getWidth(),
                wm.getDefaultDisplay().getWidth(),
                true
        );

        surfaceView = new SurfaceView(this);
        surfaceHolder = surfaceView.getHolder();
        surfaceView.setBackground(new BitmapDrawable(borderBitmap));

        surfaceView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                switch (event.getKeyCode()) {
                    case KeyEvent.KEYCODE_BACK:
                        onCloseCamera();
                }
                return false;
            }
        });

        wmParams = new WindowManager.LayoutParams();
        wmParams.width = borderBitmap.getWidth();
        wmParams.height = borderBitmap.getHeight();
        wmParams.flags = FLAG_NOT_TOUCHABLE;

        ViewGroup parent = (ViewGroup) surfaceView.getParent();
        if (parent != null) {
            parent.removeAllViews();
        }
        wm.addView(surfaceView, wmParams);

        cameraView.setOnTouchListener(new ZoomListener(this, borderBitmap) { //触摸监听
            @Override
            public void zoom(Matrix matrix) {
                surfaceView.setBackgroundResource(0); //删除背景
                canvas = surfaceHolder.lockCanvas();
                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                canvas.drawBitmap(borderBitmap, matrix, null);

                surfaceHolder.unlockCanvasAndPost(canvas);
                surfaceHolder.setFormat(PixelFormat.TRANSPARENT); //设置背景透明
                surfaceHolder.lockCanvas(new Rect(0, 0, 0, 0));
                surfaceHolder.unlockCanvasAndPost(canvas);

                lastMatrix.set(matrix);
            }
        });

    }


    @Override
    public CameraHost getCameraHost() {
        return new MyCameraHost(this);
    }

    class MyCameraHost extends SimpleCameraHost {

        private Camera.Size previewSize;

        public MyCameraHost(Context ctxt) {
            super(ctxt);
        }

        @Override
        public boolean useFullBleedPreview() {
            return true;
        }

        @Override
        public Camera.Size getPictureSize(PictureTransaction xact, Camera.Parameters parameters) {
            return previewSize;
        }

        @Override
        public Camera.Parameters adjustPreviewParameters(Camera.Parameters parameters) {
            Camera.Parameters parameters1 = super.adjustPreviewParameters(parameters);
            previewSize = parameters1.getPreviewSize();
            return parameters1;
        }

        @Override
        public void saveImage(PictureTransaction xact, byte[] image) {

            String path = FileCacheUtil.CAMERAPATH; //存储JSON的路径
            FileCacheUtil fileCacheUtil = new FileCacheUtil(path);
            //目录下只存一个临时文件，所以在保存之前，删除其余文件
            FileCacheUtil.deleteFile( new File(path));
            Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);

            Rect frame = new Rect();
            getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            int statusBarHeight = frame.top;

            bitmap = Bitmap.createBitmap(bitmap,
                    vTakePhotoRoot.getLeft(),
                    vTakePhotoRoot.getTop() + statusBarHeight,
                    vTakePhotoRoot.getWidth(),
                    vTakePhotoRoot.getHeight()
            );
            try {
                fileCacheUtil.savePicture(bitmap, "Photo");
            } catch (IOException e) {
                e.printStackTrace();
            }

            Intent intent = new Intent();
            intent.setClass(CameraActivityplus.this, HandleActivity.class);
           // intent.putExtra("id", pictureID);
            float[] matrixValues = new float[9];
            lastMatrix.getValues(matrixValues);
            intent.putExtra("matrix", matrixValues); //传递矩阵
            CameraActivityplus.this.startActivity(intent);

        }
    }
}
